package com.github.llyb120.mugen;

import cn.hutool.core.annotation.Alias;
import cn.hutool.core.util.ArrayUtil;
import lombok.*;

import java.lang.reflect.Method;
import java.util.Arrays;
import java.util.LinkedList;
import java.util.List;
import java.util.stream.Collectors;

public final class Chain {

    @Getter
    @Setter
    private LinkedList<ChainItem> stack = new LinkedList<>();
    @Getter
    @Setter
    private ChainInvokable chainInvokable;

    void pushChain(String name, Object[] parameters){
        stack.add(new ChainItem(name, copy(parameters)));
    }
    private Object[] copy(Object[] arr){
        Object[] ret = new Object[arr.length];
        System.arraycopy(arr, 0, ret, 0, arr.length);
        return ret;
    }
    void popChain(){
        if(stack.isEmpty()){
            return;
        }
        //绝不允许暗箱操作
        stack.removeLast();
    }


    @SneakyThrows
    public Object invoke(Object... args) {
        if (chainInvokable == null) {
            return null;
        }
        return chainInvokable.call(args);
    }

    public boolean checkThrough(Overrule overrule){
        List<String> list = stack.stream().map(ChainItem::getName).collect(Collectors.toList());
        int i = -1;
        for (String s : overrule.through()) {
            int _i = list.indexOf(s);
            if(_i == -1){
                return false;
            }
            if(_i < i){
                return false;
            }
            i = _i;
        }
        //最后一项必须一样
        return list.size() > 0 && overrule.through().length > 0 && list.get(list.size() - 1).equals(overrule.through()[overrule.through().length - 1]);
    }


    @AllArgsConstructor
    @Data
    public static class ChainItem {
        String name;
        Object[] parameters;
    }


    public interface ChainInvokable{
        Object call(Object... args) throws Throwable;
    }
}
